﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace GenericStateMachine.Test
{
    [TestClass]
    public class ReentrancyBlockerTest
    {
        [TestMethod]
        public void CreateScopeTest()
        {
            var obj = new ReentrancyBlocker().AsDynamic();
            Assert.AreEqual(0, obj.busyCount);
            Assert.AreEqual(false, obj.IsBusy);

            using (var scope = obj.CreateScope())
            {
                Assert.AreEqual(1, obj.busyCount);
                Assert.AreEqual(true, obj.IsBusy);
            }

            Assert.AreEqual(0, obj.busyCount);
            Assert.AreEqual(false, obj.IsBusy);
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void CreateScopeExceptionTest()
        {
            try
            {
                var obj = new ReentrancyBlocker();

                using (var scope = obj.CreateScope())
                {
                    var scope2 = obj.CreateScope();
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(string.Format("{0}: {1}", ex.GetType().Name, ex.Message));
                throw;
            }
        }

        [TestMethod]
        [ExpectedException(typeof(ObjectDisposedException))]
        public void ScopeDisposeExceptionTest()
        {
            try
            {
                var obj = new ReentrancyBlocker();
                var scope = obj.CreateScope();
                scope.Dispose();
                scope.Dispose();
            }
            catch (Exception ex)
            {
                Debug.WriteLine(string.Format("{0}: {1}", ex.GetType().Name, ex.Message));
                throw;
            }
        }

    }
}
